package mg.daloji.antandroyd.service;

import mg.daloji.antandroyd.Radio;
import mg.daloji.antandroyd.application.App;
import mg.daloji.antandroyd.mediaplayer.IMediaPlayerServiceClient;
import mg.daloji.antandroyd.mediaplayer.StatefulMediaPlayer;
import mg.daloji.antandroyd.mediaplayer.StreamStation;
import mg.daloji.antandroyd.mediaplayer.StatefulMediaPlayer.MPStates;
import mg.daloji.antandroyd.ui.Home;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;


public class ServiceRadio extends Service implements OnBufferingUpdateListener, OnInfoListener, OnPreparedListener, OnErrorListener  {
	
	private static final String TAG = ServiceRadio.class.getSimpleName();
	
	private static final int INFO = 0;
	private static final int TIMER_ERROR = 4;
	private static final long DELAY = 60000L;
	private static final int START_PLAYER=1;
	private static final int STOP_PLAYER=2;
	private static final int STREAMING=3;
	
	private Context mContext;
	private boolean  isStreaming=false;
	private Handler mHandler;
    private Radio mRadio;
    private StatefulMediaPlayer mMediaPlayer = new StatefulMediaPlayer();
	private RemoteCallbackList<IServiceRadioCallBack> mObservers = new RemoteCallbackList<IServiceRadioCallBack>();
	
	private final IServiceRadio.Stub mService = new IServiceRadio.Stub() {
		
		public String getString() throws RemoteException {
			Log.d(TAG, "getString called by " + Thread.currentThread().getName());
			return "This string is provided by Service";
		}

		public void setObserver(IServiceRadioCallBack observer)
				throws RemoteException {
			Log.d(TAG, "setObserver called by " + Thread.currentThread().getName());
			mObservers.register(observer);			
		}
		
		public void removeObserver(IServiceRadioCallBack observer)
				throws RemoteException {
			Log.d(TAG, "removeObserver called by " + Thread.currentThread().getName());
			mObservers.unregister(observer);
		}

		@Override
		public void doPause(IServiceRadioCallBack cb) throws RemoteException {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void doStop(IServiceRadioCallBack cb) throws RemoteException {
			// TODO Auto-generated method stub
			Log.i(TAG,"doStop ");
			if(cb!=null){
				mObservers.register(cb);
			}
			mHandler.sendEmptyMessage(STOP_PLAYER);
			
		}

		@Override
		public void doRelease(IServiceRadioCallBack cb) throws RemoteException {
			// TODO Auto-generated method stub
		}

		@Override
		public void doStart(IServiceRadioCallBack cb, Radio radio)
				throws RemoteException {
			// TODO Auto-generated method stub
			if(cb!=null){
				mObservers.register(cb);
			}
			Log.i(TAG, "do start "+radio.getNom() +" "+radio.getTrigramme()+"  "+radio.getUrl());
			mRadio=radio;
			
			mHandler.sendEmptyMessage(START_PLAYER);
		}

	}; 
	
	
	/**
     * Returns the contained StatefulMediaPlayer
     * @return
     */
    public StatefulMediaPlayer getMediaPlayer() {
        return mMediaPlayer;
    }

    /**
     * Initializes a StatefulMediaPlayer for streaming playback of the provided StreamStation
     * @param station The StreamStation representing the station to play
     */
    public void initializePlayer(StreamStation station) {
        //mClient.onInitializePlayerStart("Connecting...");
        mMediaPlayer = new StatefulMediaPlayer(station);
        mMediaPlayer.setOnBufferingUpdateListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.prepareAsync();
    }
    
    /**
     * Initializes a StatefulMediaPlayer for streaming playback of the provided stream url
     * @param streamUrl The URL of the stream to play.
     */
    public void initializePlayer(String streamUrl) {
    	if(streamUrl!=null){
    		mMediaPlayer = new StatefulMediaPlayer();
    		mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    		try {
    			mMediaPlayer.setDataSource(streamUrl);
    		}
    		catch (Exception e) {
    			Log.e("MediaPlayerService", "error setting data source");
    			mMediaPlayer.setState(MPStates.ERROR);
    		}
    		mMediaPlayer.setOnBufferingUpdateListener(this);
    		mMediaPlayer.setOnInfoListener(this);
    		mMediaPlayer.setOnPreparedListener(this);
    		mMediaPlayer.prepareAsync();
    	}
    }
    
    /**
     * Stops the contained StatefulMediaPlayer.
     */
    public void stopMediaPlayer() {
        stopForeground(true);
        mMediaPlayer.stop();
        mMediaPlayer.release();
    }
    
    public void resetMediaPlaer() {
        stopForeground(true);
        mMediaPlayer.reset();
    }
    
    /**
     * Pauses the contained StatefulMediaPlayer
     */
    public void pauseMediaPlayer() {
        Log.d("MediaPlayerService","pauseMediaPlayer() called");
        mMediaPlayer.pause();
        stopForeground(true);
 
    }
    
    /**
     * Starts the contained StatefulMediaPlayer and foregrounds the service to support
     * persisted background playback.
     */
    public void startMediaPlayer() {
        Context context = getApplicationContext();
 
        //set to foreground
        Notification notification = new Notification(android.R.drawable.ic_media_play, "Antandroyd",
                System.currentTimeMillis());
        Intent notificationIntent = new Intent(this, Home.class);
        notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
 
        CharSequence contentTitle = "Antandroyd";
        CharSequence contentText = mRadio.getNom();
        notification.setLatestEventInfo(context, contentTitle,
                contentText, pendingIntent);
        startForeground(1, notification);
 
        Log.d("MediaPlayerService","startMediaPlayer() called");
        mMediaPlayer.start();
    }
    
	@Override
	public IBinder onBind(Intent arg0) {
		return mService;
	}

	@Override
	public boolean onUnbind(Intent intent) {
		Toast.makeText(mContext, "onUnbind called by "
			  + Thread.currentThread().getName(), Toast.LENGTH_LONG).show();
		return true;
	}

	@Override
	public void onCreate() {
		mContext = this;
		
		mHandler = new Handler(){
			@Override
			public void handleMessage(Message msg) {
				switch(msg.what){
				   case STREAMING:
					   		isStreaming=true;
							int observerNum = mObservers.beginBroadcast();
							for(int i = 0; i < observerNum; i++){
							  try {
								mObservers.getBroadcastItem(i).streamingReady();
							  	} catch (RemoteException e) {
							  	Log.e(TAG, "Error "+e.getMessage());	
							  }
							}
							mObservers.finishBroadcast();
							break;
							
				   case START_PLAYER:
					        isStreaming=false;
					        mHandler.sendEmptyMessageDelayed(TIMER_ERROR, DELAY);
					   		initializePlayer(mRadio.getUrl());
					   		startMediaPlayer();
					     break;
					 
				   case STOP_PLAYER:
					   isStreaming=false;
					   stopMediaPlayer();
				     break; 
				     
				   case TIMER_ERROR:
					   if(!isStreaming){
						   int observer = mObservers.beginBroadcast();
							for(int i = 0; i < observer; i++){
							  try {
								 mObservers.getBroadcastItem(i).errorStreaming();
								 Log.e(TAG, "dismiss progress");	
							  	} catch (RemoteException e) {
							  	Log.e(TAG, "Error "+e.getMessage());	
							  }
							}
							mObservers.finishBroadcast();
							break;
					   }
				     break;     
				
				}
			}
			
		};
		

		super.onCreate();
	}

	@Override
	public void onDestroy() {
		Toast.makeText(mContext, "onDestroy called by "
			  + Thread.currentThread().getName(), Toast.LENGTH_LONG).show();
		super.onDestroy();
	}

	@Override
	public void onRebind(Intent intent) {
		Toast.makeText(mContext, "onRebind called by "
			  + Thread.currentThread().getName(), Toast.LENGTH_LONG).show();
		super.onRebind(intent);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Toast.makeText(mContext, "onStartCommand called by "
			  + Thread.currentThread().getName(), Toast.LENGTH_LONG).show();
		Log.i(TAG, "onStartCommand called by");
		return START_STICKY;
	}

	@Override
	public boolean onError(MediaPlayer arg0, int what, int extra) {
		// TODO Auto-generated method stub
		Log.i("info", "onError  what:" +what +"extra:"+extra);
		mMediaPlayer.reset();
		return true;
	}

	@Override
	public void onPrepared(MediaPlayer arg0) {
		// TODO Auto-generated method stub
		Log.i("info", "onPrepared  OOKKOOK");
	 	mHandler.sendEmptyMessage(STREAMING);
		 startMediaPlayer();
	}

	@Override
	public boolean onInfo(MediaPlayer mp, int what, int extra) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		// TODO Auto-generated method stub
		
	}
	
}